<template>
	<view class="previewLayout">
		<swiper class="swiper" circular :current="current" @change="onSwiperChange">
			<swiper-item class="swiper-item" v-for="(item,index) in priviews" :key="index">
				<view class="image-container">
					<!-- Loading 动画 -->
					<view 
					  v-if="!item.isLoaded" 
					  class="loading-layer"
					>
					  <view class="loading-spinner"></view>
					</view>
					
					<!-- 图片组件 -->
					<image v-if="Math.abs(index-current) <= 5" :src="cloudIdToUrl(item.picurl)" mode="aspectFill" @click="maskToggle" lazy-load
					class="image" :class="{ 'loaded': item.isLoaded }" @load="handleImageLoad(item)"></image>
				</view>
			</swiper-item>
		</swiper>
		<view class="mask" v-if="maskShow">
			<view class="goBack topIcon" :style="{top: goBackTop + 'px'}"
			@click="goBack">
				<!-- 如果priviews中只有一条数据(比如：分享页面)，则返回按钮变为访问首页按钮 -->
				<uni-icons v-if="priviews.length>1" type="back" color="#fff" size="20"></uni-icons>
				<uni-icons v-else type="home-filled" color="#fff" size="20"></uni-icons>
			</view>
			<!-- <view class="favorite topIcon" :style="{top: goBackTop + 'px'}" @click="toggleFavorite(pic._id)">
				<uni-icons v-if="pic.isFavorite" type="heart-filled" color="red" size="20"></uni-icons>
				<uni-icons v-else type="heart" color="#fff" size="20"></uni-icons>
			</view> -->
			<view class="count">{{ (current + 1) + ' / ' + priviews.length}}</view>
			<view class="time"><uni-dateformat :date="new Date()" format="hh : mm" /></view>
			<view class="date"><uni-dateformat :date="new Date()" format="MM 月 dd日" /></view>
			<view class="footer">
				<view class="box" @click="openInfo">
					<uni-icons type="info" size="24"></uni-icons>
					<view class="text">信息</view>
				</view>
				<view class="box" @click="toggleFavorite(pic._id)">
					<uni-icons v-if="pic.isFavorite" type="heart-filled" color="red" size="20"></uni-icons>
					<uni-icons v-else type="heart" size="24"></uni-icons>
					<view class="text">收藏</view>
				</view>
				<view class="box" @click="openSorce">
					<uni-icons v-if="pic.userScore>0" type="star-filled" size="24" color="red"></uni-icons>
					<uni-icons v-else type="star" size="24"></uni-icons>
					<view class="text">{{pic.score}}分</view>
				</view>
				<view class="box" @click="download" :class="{ 'disabled': isDownloading }" >
					<uni-icons v-if="pic.downloadCount>0" type="download-filled" size="24" color="red"></uni-icons>
					<uni-icons v-else type="download" size="24"></uni-icons>
					<view class="text">下载</view>
				</view>
			</view>
		</view>
		
		<uni-popup ref="infoPopup" type="bottom" :safe-area="false">
			<view class="infoPopup">
				<view class="popHeader">
					<view class=""></view>
					<view class="title">壁纸信息</view>
					<view class="closeIcon" @click="closeInfo">
						<uni-icons type="closeempty" size="18" color="#999"></uni-icons>
					</view>
				</view>
				<scroll-view scroll-y class="scrollView">
					<view class="content">
						<view class="row">
							<view class="label">壁纸ID:</view>
							<text class="value" selectable="">{{pic._id}}</text>
						</view>
						<view class="row">
							<view class="label">发布者:</view>
							<text class="value" selectable="">{{pic.nickname}}</text>
						</view>
						<view class="row">
							<view class="label">评分:</view>
							<view class="value scoreBox">
								<uni-rate :size="18" :value="pic.score" readonly/>
								<text class="score">{{pic.score}}分</text>
							</view>
						</view>
						<view class="row">
							<view class="label">摘要:</view>
							<view class="value">
								{{pic.description}}
							</view>
						</view>
						<view class="row">
							<view class="label">标签:</view>
							<view class="value tags">
								<uni-tag v-for="(tagitem, tagindex) in pic.tabs" :text="tagitem" :inverted="true" type="success" circle class="tag" :key="tagindex"></uni-tag>
							</view>
						</view>
						<view class="copyright">
							声明：本图片来自于投稿，非商业使用，用于免费学习交流，如果侵犯了您的权益，您可以拷贝壁纸ID举报到平台。
						</view>
					</view>
				</scroll-view>
			</view>
		</uni-popup>
		
		<uni-popup ref="scorePopup" :is-mask-click="false">
			<view class="scorePopup">
				<view class="popHeader">
					<view class=""></view>
					<view class="title">壁纸评分</view>
					<view class="closeIcon" @click="closeSorce">
						<uni-icons type="closeempty" size="18" color="#999"></uni-icons>
					</view>
				</view>
				<view class="content">
					<view class="value scoreBox">
						<uni-rate :size="30" v-model="myscore" :readonly="pic.userScore>0" allowHalf/>
						<text class="score">{{myscore}}分</text>
					</view>
				</view>
				<view class="footer">
					<button type="default" plain size="mini" @click="doSorce" :disabled="pic.userScore > 0 || myscore==0">{{!pic.userScore? '确认评分':'已评分'}}</button>
				</view>
			</view>
		</uni-popup>
	</view>
</template>

<script setup>
	import {ref} from 'vue'
	import { onLoad, onReachBottom, onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
	import { apiGetImageById, apiGetImageDetailById, apiToggleFavorite, apiRateWallpaper,apiDownloadWallpaperLog } from '@/api/index.js'
	import { cloudIdToUrl, getImageNameFromUrl } from '@/utils/common.js'
	import { isLoggedIn } from "@/utils/user.js"
	
	const hasLogin = ref(false) // 是否已登录
	const priviews = ref([])
	const current = ref(0)
	const pic = ref({
		score:0
	})
	
	// 页面加载
	onLoad( async (e)  => {
		let id = e.id || ''
		let temp = []
		// 此处做特殊处理，比如：把URL分享给其他人，或者微信小程序中的分享，当用户直接使用 /pages/preview/preview?id=6543440409664cd61412021d访问是
		// uni.getStorageSync('priviews')就可能得不到数据，因此就需要通过id=6543440409664cd61412021请求接口，返回该详细信息
		try {
			temp = uni.getStorageSync('priviews')
			if(!temp) {
				let data = await apiGetImageById({id})
				temp = data
			}
		} catch (error) {
			// 
		}
		
		hasLogin.value = await isLoggedIn({checkToken:true})
		
		temp.forEach(item => {
		    item.isLoaded = false; // 图片是否加载
		    item.isLoadedDetail = false; // 是否加载明细数据
			// 当preivews中预览的是我的下载、我的评分、我的收藏图片时，需要把item._id变为item.wallpaper_id
			if(item.wallpaper_id) {
				item._id = item.wallpaper_id
			}
		    if (typeof item.score === 'string') {
		        item.score = parseFloat(item.score);
		    }
		    if (!isNaN(item.score)) {
		        item.score = parseFloat(item.score.toFixed(1));
		    }
		});
		priviews.value = temp
		current.value = priviews.value.findIndex(item=> item._id == id)
		pic.value = priviews.value[current.value]
		// 初始加载详情
		await loadDetail()
	})
	
	// 根据current.value, 加载 priviews中 current 及 前 后 共3条记录的详细信息，并合并更新到priviews数组中
	const loadDetail = async () => {
	  try {
	    const total = priviews.value.length;
	    if (total === 0) return;
	
	    // 计算需要加载的索引（处理循环情况）
	    const indexesToLoad = [
	      current.value,
	      (current.value - 1 + total) % total, // 前一张（处理循环）
	      (current.value + 1) % total          // 后一张（处理循环）
	    ];
	
	    // 去重（当total=1或2时可能有重复）
	    const uniqueIndexes = [...new Set(indexesToLoad)];
	
	    // 使用循环逐个加载
	    for (const index of uniqueIndexes) {
	      // 跳过已加载的
	      if (priviews.value[index].isLoadedDetail) continue;
	
	      try {
	        const data = await apiGetImageDetailById({ 
	          id: priviews.value[index]._id 
	        });
	        
			  // 直接更新对应数据
			  priviews.value[index] = {
				...priviews.value[index],
				...data,
				isLoadedDetail: true
			  };
			  
			  // 如果是当前显示的壁纸，更新pic.value
			  if (index === current.value) {
				pic.value = priviews.value[index];
			  }
	      } catch (e) {
	        console.error(`加载壁纸 ${priviews.value[index]._id} 详情失败:`, e);
	        // 设置默认值
	        priviews.value[index] = {
	          ...priviews.value[index],
	          isFavorite: false,
	          userScore: null,
	          downloadCount: 0,
	          isLoadedDetail: true
	        };
	      }
	    }
		// console.log('pic.value=',pic.value)
	  } catch (e) {
	    console.error('加载壁纸详情主流程出错:', e);
	  }
	};
	
	const onSwiperChange = (e) => {
		current.value = e.detail.current
		pic.value = priviews.value[current.value]
		loadDetail() // 滑动后加载详情
	}
	
		
	// 通过样式与在数据中增加isLoaded字段，处理图片太大或网络太慢导致有图片未加载问题
	const handleImageLoad = (item) => {
		item.isLoaded = true // 加载完成后更新状态
	}
	
	// 点击收藏或取消收藏
	const toggleFavorite = async (id) => {
		const data = await apiToggleFavorite({id},{toLogin:true})
		pic.value.isFavorite = data.isFavorite
	}
	
	import {getStatusBarHeight} from '@/utils/system.js'
	const goBackTop = getStatusBarHeight() > 0 ? getStatusBarHeight() : 20
	// 遮罩层处理
	const maskShow = ref(true)
	const maskToggle = () => {
		maskShow.value = !maskShow.value
		// console.log(maskShow.value)
	}
	
	// 信息弹出框
	const infoPopup = ref(null)
	const openInfo = () => {
		infoPopup.value.open()
	}
	const closeInfo = () => {
		infoPopup.value.close()
	}
	
	// 评分弹出框
	const scorePopup = ref(null)
	const myscore = ref(0) // 我的评分
	const openSorce = () => {
		if(pic.value.userScore) {
			myscore.value = pic.value.userScore
		} else {
			myscore.value = 0
		}
		scorePopup.value.open()
	}
	const closeSorce = () => {
		scorePopup.value.close()
	}
	const doSorce = async () => {
		try {
			const data = await apiRateWallpaper({id:pic.value._id, score:myscore.value},{toLogin:true})
			pic.value.userScore = myscore
			pic.value.score = data.score
			uni.showToast({
				title: '评分成功'
			})
			closeSorce()
		} catch (error) {
			//TODO handle the exception
		}
	}
	
	// 添加base64转ArrayBuffer的方法
	const base64ToArrayBuffer = (base64) => {
	  const binaryString = wx.base64ToArrayBuffer(base64);
	  const bytes = new Uint8Array(binaryString);
	  return bytes.buffer;
	}
	
	
	// 下载图片
	const isDownloading = ref(false)
	const download = async () => {
	  if(!hasLogin.value) {
		  uni.showToast({
		    title: '请先登录',
		    icon: 'none',
		    duration: 1000,
		  });
		  return
	  }
	  if (isDownloading.value) return;
	  isDownloading.value = true;
	  uni.showLoading({ title: '下载中...', mask: true });
	
	  try {
	    const imageUrl = cloudIdToUrl(pic.value.picurl)
	  
	  
	    // #ifdef MP-WEIXIN
	    // 微信小程序环境
	    const downloadRes = await uni.downloadFile({
	      url: imageUrl,
	    });
	  
	    if (downloadRes.statusCode !== 200) {
	      throw new Error('图片下载失败');
	    }
	  
	    try {
	      await uni.saveImageToPhotosAlbum({
	        filePath: downloadRes.tempFilePath,
	      });
	      uni.showToast({
	        title: '图片已保存到相册',
	        icon: 'none',
	      });
	    } catch (saveError) {
	      if (saveError.errMsg.includes('auth deny')) {
	        uni.showModal({
	          title: '权限申请',
	          content: '需要授权才能保存图片到相册',
	          success: (res) => {
	            if (res.confirm) {
	              uni.openSetting();
	            }
	          },
	        });
	      } else {
	        uni.showToast({
	          title: `保存失败：${saveError.message || saveError.errMsg}`,
	          icon: 'none',
	          duration: 2000,
	        });
	      }
	    }
	    // #endif
	  
	    // #ifdef H5
	    // H5 环境
	  	const response = await fetch(imageUrl);
	  	const blob = await response.blob();
	  	const url = URL.createObjectURL(blob);
	  	const a = document.createElement('a');
	  	a.href = url;
	  	a.download = Math.floor(Math.random() * 10000) + getImageNameFromUrl(imageUrl);
	  	document.body.appendChild(a);
	  	a.click();
	  	document.body.removeChild(a);
	  	setTimeout(() => URL.revokeObjectURL(url), 100);
	    // #endif
		
		// 增加下载壁纸日志
		try {
			await apiDownloadWallpaperLog({id:pic.value._id})
			pic.value.downloadCount = 1
		} catch (error) {
			//TODO handle the exception
			console.warn('apiDownloadWallpaperLog错误:' + error)
		}
		
	  } catch (error) {
	    uni.showToast({
	      title: `操作失败：${error.message || error.errMsg}`,
	      icon: 'none',
	      duration: 2000,
	    });
	  }
	  finally {
	    isDownloading.value = false;
	    uni.hideLoading();
	  }
	};

const goBack = () => {
    // 获取当前页面栈
    const pages = getCurrentPages();
    // 如果priviews中只有一条数据(比如：分享页面)，则返回按钮变为访问首页按钮
    if (priviews.value.length > 1 && pages.length > 1) {
        uni.navigateBack();
    } else {
        uni.switchTab({
            url: '/pages/index/index'
        });
    }
};
	
	// 分享给好友
	onShareAppMessage(e=>{
		return {
			title: "咸虾米壁纸",
			path:'/pages/preview/preview?id=' + pic.value._id
		}
	})
	
	// 分享朋友圈
	onShareTimeline(e=>{
		return {
			title: '咸虾米壁纸',
			query: 'id=' + pic._id
		}
	})
	
</script>

<style lang="scss" scoped>
.previewLayout{
	width: 100%;
	height: 100vh;
	position: relative;
	z-index: 1;
	.swiper{
		width: 100%;
		height: 100%;
		.swiper-item{
			background: #f0f0f0 no-repeat center;
			width: 100%;
			height: 100%;
			.image-container {
			  position: relative;
			  width: 100%;
			  height: 100%;
			  .image{
			  	width: 100%;
			  	height: 100%;
			  }
			  /* Loading遮罩层 */
			  .loading-layer {
			    position: absolute;
			    top: 0;
			    left: 0;
			    width: 100%;
			    height: 100%;
			    background: rgba(0, 0, 0, 0.2);
			    display: flex;
			    align-items: center;
			    justify-content: center;
			    z-index: 2;
			  }
			  
			  /* 加载动画 */
			  .loading-spinner {
			    width: 40rpx;
			    height: 40rpx;
			    border: 4rpx solid #fff;
			    border-radius: 50%;
			    border-top-color: transparent;
			    animation: spin 0.8s linear infinite;
			  }
			  
			  @keyframes spin {
			    to {
			      transform: rotate(360deg);
			    }
			  }
			}
			
		}
	}
}
.mask{
	width: 100%;
	&>view{ // 提取公共样式
		position: absolute;
		z-index: 2;
		left: 0;
		right:0;
		margin: auto;
		width: fit-content; // 根据内容自动计算合适宽度
	}
	.topIcon{
		width: 38px;
		height: 38px;
		background: rgba(0, 0, 0, 0.5);
		backdrop-filter: blur(10rpx);
		margin-left: 0;
		border: 1px solid rgba(255, 255, 255, 0.3);
		border-radius: 50%;
		display: flex;
		justify-content: center;
		align-items: center;
	}
	.goBack{
		left: 30px;
		top:0;
	}
	.favorite{
		left: 630rpx;
		top:0;
	}
	.count{
		top: 10vh;
		height: 40rpx;
		line-height: 40rpx;
		background: rgba(0, 0, 0, 0.3);
		backdrop-filter: blur(10rpx); // 设置背景模糊
		font-size: 26rpx;
		color: rgba(255, 255, 255, 0.7);
		border-radius: 40rpx;
		padding: 8rpx 28rpx;
		display: flex;
		align-items: center;
	}
	.time{
		top: calc(10vh + 80rpx);
		height: 120rpx;
		color: #fff;
		font-size: 140rpx;
		text-align: center;
		text-shadow: 0 4rpx rgba(0, 0, 0, 0.3);
	}
	.date{
		top: calc(10vh + 280rpx);
		font-size: 34rpx;
		color: rgba(255, 255, 255, 0.8);
		text-shadow: 0 2rpx rgba(0, 0, 0, 0.3);
		text-align: center;
	}
	.footer{
		top: 80vh;
		width: 65vw;
		height: 120rpx;
		background-color: rgba(255, 255, 255, 0.8);
		backdrop-filter: blur(10rpx); // 设置背景模糊
		border-radius: 60rpx;
		display: flex;
		justify-content: space-around;
		align-items: center;
		box-shadow: 0 4rpx rgba(0, 0, 0, 0.3);
		
		.box{
			text-align: center; 
			font-size: 26rpx;
			padding: 10rpx 10rpx;
			.text{
				margin-top: 10rpx;
				color: $text-color-sub;
			}
		}
		
		
		/* 禁用状态的视觉反馈 */
		.disabled {
		  opacity: 0.6;
		  pointer-events: none; /* 阻止点击事件（H5生效） */
		}
	}
}
.infoPopup{
	background-color: #fff;
	border-radius: 20rpx 20rpx 0 0;
	overflow: hidden;
	/* 通过增加padding 来将iphone手机底部安全区给遮罩住*/
	padding: 20rpx 20rpx 60rpx 20rpx;
	.popHeader{
		display: flex;
		align-items: center;
		justify-content: space-between;
		.title{
			color: $text-color-sub;
			font-size: 26rpx;
		}
		.closeIcon{
			padding: 6rpx;
		}
	}
	.scrollView{
		max-height: 50vh;
		.content{
			.row{
				display: flex;
				align-items: flex-start;
				padding: 16rpx 0;
				font-size: 26rpx;
				line-height: 1.7em;
				.label{
					color: $text-color-sub;
					width: 140rpx;
					text-align: right;
				}
				.value{
					color: $text-color-mian;
					margin-left: 10rpx;
					flex: 1;
					width: 0; // 兼容性写法，当value内容很多时，不会把label给挤压掉
				}
				.scoreBox{
					display: flex;
					align-items: center;
					.score{
						margin-left: 20rpx;
						color: rgb(255, 202, 62);
					}
				}
				.tags{
					display: flex;
					align-items: center;
					flex-wrap: wrap;
					.tag{
						// border: 1px solid $brand-theme-color; // 小程序不支持
						color: $brand-theme-color;
						font-size: 22rpx;
						// padding: 10rpx 30rpx; // 小程序不支持
						border-radius: 40rpx;
						line-height: 1em;
						margin: 0 10rpx 10rpx 0;
					}
				}
			}
			.copyright{
				padding: 16rpx;
				color: $text-color-grey;
				font-size: 22rpx;
				background: #eee;
				border-radius: 10rpx;
				line-height: 1.6em;
			}
		}
	}
}

.scorePopup{
	background-color: #fff;
	border-radius: 20rpx;
	overflow: hidden;
	padding: 20rpx 20rpx 0 20rpx;
	
	width: 70vw;
	height: 300rpx;
	
	display: flex;
	flex-direction: column;
	
	.popHeader{
		display: flex;
		align-items: center;
		justify-content: space-between;
		.title{
			color: $text-color-sub;
			font-size: 26rpx;
		}
		.closeIcon{
			padding: 6rpx;
		}
	}
	
	.content{
		.scoreBox{
			display: flex;
			align-items: center;
			.score{
				margin-left: 20rpx;
				color: rgb(255, 202, 62);
			}
		}
		flex: 1;
		margin: 40rpx auto;
	}
	
	.footer{
		text-align: center;
	}
	
}
</style>
